import { beforeDDL } from "../utils/DateUtils";
import { StateMoal } from "./StateMoal";
import { StageData, StageList, TaskIdsModal } from "./stage";
import type { RemoveMethods } from "@/types/remove-methods";
import { SurfaceSetting } from "@model/surfaceSetting";

export class TimeMentionModal {
  type: number; // 1表示任务性，2表示习惯性
  deadLine: number | null; // 截止日期
  beforeDDL2Mention: number; // 在截止日期前多久提醒
  beforeDDL2MentionUnit: number; //在截止日期前多久提醒周期单位，例如1代表天，2代表月，3代表年,
  beginMentionTime: number; // 第一次打卡时间，用于习惯性任务
  mentionFlag: number; // 提醒周期标志，是每：1，还是自定义:2
  mentionPeriod: number | string; // 提醒周期。若是自定义，则以逗号分割，例如1,2,3代表隔
  mentionPos: number; //自定义时，代表处在第几个
  mentionUnit: number; //提醒周期单位，例如1代表天，2代表月，3代表年,

  static copyTimeMentionModal(data: RemoveMethods<TimeMentionModal>) {
    const timeModel = new TimeMentionModal();
    Object.assign(timeModel, data);
    return timeModel;
  }

  static change2NextClockTime(time: TimeMentionModal) {
    const newTime = TimeMentionModal.copyTimeMentionModal(time);
    if (newTime.type === 2) {
      if (newTime.mentionFlag === 1 && typeof newTime.mentionPeriod == "number") {
        const ddl = beforeDDL(newTime.beginMentionTime, newTime.mentionPeriod, newTime.mentionUnit);
        newTime.beginMentionTime = ddl;
      }
      if (time.mentionFlag === 2) {
        newTime.mentionPos += 1;
      }
    }
    return newTime;
  }

  static computeNextClockTime(time: TimeMentionModal): number {
    try {
      if (time.type === 2) {
        if (time.mentionFlag === 1 && typeof time.mentionPeriod == "number") {
          const ddl = beforeDDL(time.beginMentionTime, time.mentionPeriod, time.mentionUnit);
          return ddl;
        }
        if (time.mentionFlag === 2) {
          const strings = (time.mentionPeriod + "").split(",");
          if (strings.length >= time.mentionPos) {
            let num = 0;
            strings.forEach((value, index) => {
              if (index < time.mentionPos) num += parseInt(value);
            });
            const ddl = beforeDDL(time.beginMentionTime, num, time.mentionUnit);
            return ddl;
          }
        }
      }
    } catch (e) {
      return 0;
    }
    return 0;
  }

  static computeMentionTime(time: TimeMentionModal) {
    try {
      if (time !== undefined) {
        if (time.type === 1) {
          return beforeDDL(time.deadLine, time.beforeDDL2Mention, time.beforeDDL2MentionUnit);
        }
        if (time.type === 2) {
          const ddl = TimeMentionModal.computeNextClockTime(time);
          time.deadLine = ddl;
          return beforeDDL(ddl, time.beforeDDL2Mention, time.beforeDDL2MentionUnit);
        }
      }
    } catch (e) {
      return 0;
    }
    return 0;
  }

  static getMentionFlagMap() {
    return [
      {
        label: "每",
        value: 1,
      },
      {
        label: "自定义",
        value: 2,
      },
    ];
  }

  static getMentionUnitMap() {
    return [
      {
        label: "天",
        value: 1,
      },
      {
        label: "月",
        value: 2,
      },
      {
        label: "年",
        value: 3,
      },
    ];
  }

  static setClockBased(
    model: TimeMentionModal,
    beforeDDL2Mention: number,
    beforeDDL2MentionUnit: number,
    beginMentionTime: number,
    mentionFlag: number,
    mentionPeriod: number | string,
    mentionPos: number,
    mentionUnit: number,
  ) {
    if (model !== undefined) {
      model.type = 2;
      model.deadLine = 0;
      model.beforeDDL2Mention = beforeDDL2Mention;
      model.beginMentionTime = beginMentionTime;
      model.mentionFlag = mentionFlag;
      model.mentionPeriod = mentionPeriod;
      model.mentionPos = mentionPos;
      model.mentionUnit = mentionUnit;
      model.beforeDDL2MentionUnit = beforeDDL2MentionUnit;
    }
    return model;
  }

  static setTaskBased(
    model: TimeMentionModal,
    deadLine: number | null,
    beforeDDL2Mention: number,
    beforeDDL2MentionUnit: number,
  ) {
    if (model !== undefined) {
      model.type = 1;
      model.deadLine = deadLine;
      model.beforeDDL2Mention = beforeDDL2Mention;
      model.beginMentionTime = 0;
      model.mentionFlag = 0;
      model.mentionPeriod = 0;
      model.mentionPos = 0;
      model.mentionUnit = 0;
      model.beforeDDL2MentionUnit = beforeDDL2MentionUnit;
    }
    return model;
  }
}

export class TaskData {
  id: number;
  name: string;
  fatherId: number; // stageId
  mentionTime: number;
  desc: string;
  type: number; // 1代表任务型，2代表打卡型
  timeMentionModal: TimeMentionModal;
  finishTime: number; // 完成次数
  failTime: number; // 失败次数

  constructor(
    id: number,
    name: string,
    type: number,
    fatherId: number,
    desc: string,
    timeMentionModal: TimeMentionModal,
  ) {
    this.id = id;
    this.name = name;
    this.type = type;
    this.fatherId = fatherId;
    this.mentionTime = TimeMentionModal.computeMentionTime(timeMentionModal);
    this.desc = desc;
    this.timeMentionModal = timeMentionModal;
    this.finishTime = 0;
    this.failTime = 0;
  }

  static getTypeStr(type: number): string {
    if (type === 1) return "任务型";
    if (type === 2) return "打卡型";
    return "";
  }
  static getTypeNum(str: string): number {
    if (str === "任务型") return 1;
    if (str === "打卡型") return 2;
    return -1;
  }
  static getTypeOptions() {
    const result = new Array<{ label: string; value: number }>();
    result.push({ label: "任务型", value: 1 });
    result.push({ label: "打卡型", value: 2 });
    return result;
  }
}

export class TaskList {
  taskData: Array<TaskData>;

  setInfo(data: RemoveMethods<TaskList>) {
    Object.assign(this, data);
  }
  constructor(taskData: Array<TaskData>) {
    this.taskData = taskData;
  }

  getTaskDataById(id: number | undefined) {
    return this.taskData.find(item => item.id === id);
  }
  addTaskData(data: TaskData) {
    this.taskData.push(data);
  }
  deleteTaskDataById(id: number) {
    this.taskData = this.taskData.filter(item => item.id !== id);
  }
  getTaskSelectOptions(stageData: StageData | undefined) {
    const result = [];
    if (stageData !== undefined) {
      const task = stageData.task;
      const list = new Set<number>();
      StateMoal.getAllId(task.TaskBased, list, true, true, true);
      StateMoal.getAllId(task.ClockBased, list, true, true, true);
      for (let i = 0; i < this.taskData.length; i++) {
        const data = this.taskData[i];
        if (list.has(data.id)) {
          result.push({
            label: data.name,
            value: data.id,
          });
        }
      }
    }
    return result;
  }

  finishTask(
    taskId: number,
    taskType: number,
    origianlState: string,
    stageList: StageList,
    surfaceSetting: SurfaceSetting,
    key: string,
  ) {
    // console.log(row);
    const taskData = this.getTaskDataById(taskId);
    // console.log(taskData);
    if (taskData !== undefined) {
      if (key === "finish") taskData.finishTime = (taskData.finishTime ? taskData.finishTime : 0) + 1;
      if (key === "fail") taskData.failTime = (taskData.failTime ? taskData.failTime : 0) + 1;
      let finish = false;
      if (taskType === 1) finish = true; // 直接变成已结束
      if (taskType === 2) {
        taskData.timeMentionModal = TimeMentionModal.change2NextClockTime(taskData.timeMentionModal);
        const time = TimeMentionModal.computeNextClockTime(taskData.timeMentionModal);
        if (!(time > 0)) finish = true; // 变成已结束
        else taskData.mentionTime = TimeMentionModal.computeMentionTime(taskData.timeMentionModal);
      }
      const showStage = taskData.fatherId;
      const satgeData = stageList.getStageDataById(showStage);
      if (satgeData !== undefined) {
        const stateMoal = TaskIdsModal.getStateModal4Task(satgeData?.task, taskType);
        if (stateMoal !== undefined && finish) {
          StateMoal.changeIdState(stateMoal, taskData.id, origianlState, "finished");
          surfaceSetting.taskBoardList.key = new Date().getTime();
        }
      }
    }
  }
}
